import time
from functools import wraps
# from logger_config import get_logger_root
import signal
import logging
logger = logging.getLogger('graph_algorithm.log')


def iolog(is_api=True, log_input=True, log_output=True):
    """
    打印输入参数和输出内容log
    :param is_api: 是否是api
    :param log_input: 是否记录输入参数
    :param log_output: 是否记录输出参数
    :return:
    """
    def wrapper(func):
        @wraps(func)
        def inner_wrapper(*args, **kwargs):
            # 输入
            if log_input:
                if is_api:
                    request = args[0]
                    input_str = str(request.body, encoding='utf-8')
                else:
                    args_str = ', '.join([str(arg) for arg in args])
                    kwargs_str = ', '.join(['{}={}'.format(key, value) for key, value in kwargs.items()])
                    input_str = args_str + (', ' if args_str and kwargs_str else '') + kwargs_str
                logger.info('{} 输入：{}'.format(func.__name__, input_str))

            result = func(*args, **kwargs)

            # 输出
            if log_output:
                if is_api:
                    logger.info('{} 输出：{}'.format(func.__name__, str(result.content, encoding='utf-8')))
                else:
                    logger.info('{} 输出：{}'.format(func.__name__, result))

            return result
        return inner_wrapper

    return wrapper


def sep_log(sep='-', sep_num=20, log_start=True, log_end=True):
    """
    装饰器，在函数前后打印分隔符
    :param sep: 分隔符
    :param sep_num: 分隔符数量
    :param log_start: 是否在函数前打印分隔符
    :param log_end: 是否在函数后打印分隔符
    :return:
    """

    def wrapper(func):
        @wraps(func)
        def inner_wrapper(*args, **kwargs):
            if log_start:
                logger.info(sep * sep_num + '    ' + func.__name__ + ': start' + '    ' + sep * sep_num)
            result = func(*args, **kwargs)
            if log_end:
                logger.info(sep * sep_num + '    ' + func.__name__ + ': end' + '    ' + sep * sep_num)
            return result

        return inner_wrapper

    return wrapper


def time_log(log_start=True):
    """
    打印函数的运行时间日志
    :param log_start: 是否打印计时开始标记
    :return:
    """

    def wrapper(func):
        @wraps(func)
        def inner_wrapper(*args, **kwargs):
            if log_start:
                logger.info('{} 计时开始...'.format(func.__name__))
            start_t = time.time()
            result = func(*args, **kwargs)
            logger.info('{} 耗时:{}秒'.format(func.__name__, time.time() - start_t))
            return result
        return inner_wrapper

    return wrapper


def timeout(secs):
    """
    超时secs秒数发起TimeOutError异常
    :param secs:
    :return:
    """
    def dec(func):
        def handler(signum,frame):
            raise TimeoutError("函数执行超时")
        def wrapper(*args,**kwargs):
            try:
                signal.signal(signal.SIGALRM,handler)
                signal.alarm(secs)
                result = func(*args,**kwargs)
                signal.alarm(0)
                return result
            except Exception as e:
                logger.error(e)
                raise e
        return wrapper
    return dec

